import { ChooseScanType } from '@renderer/views/multiScanSeriesPage/helper/types'
import { BaseScanSeries, EnumScanStatus, NormalScanSeries } from '@renderer/views/multiScanSeriesPage/types'
import { initBallsPosition } from '@renderer/views/multiScanSeriesPage/helper/helper'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useGlobalLoading } from '@renderer/utils/hooks/useGlobalLoading'

const { hideLoading } = useGlobalLoading()

export class ScanSeries {
  scanSeriesArr: any
  activeScanSeries: any
  activeImageId: number | string
  imageId2seriesIdMap: Map<any, any>


  constructor() {
    this.scanSeriesArr = []
    this.activeScanSeries = {
      id: '', // series的id
      scanType: ''
    }
    this.activeImageId = ''
    this.imageId2seriesIdMap = new Map()
  }

  updateActiveImageId(id: string) {
    this.activeImageId = id
  }

  getActiveImageId() {
    return this.activeImageId
  }

  getRecentScoutSeries() {
    const lastIndex = this.scanSeriesArr.findLastIndex(series => series.scanType === ChooseScanType.scout)
    if (lastIndex === -1) {
      return null
    }
    return this.scanSeriesArr[lastIndex]
  }

  getSeriesById(id: number | string): NormalScanSeries | BaseScanSeries | null {
    const scanIndex = this.scanSeriesArr.findIndex(series => series.id === id)
    if (scanIndex === -1) {
      return null
    } else {
      return this.scanSeriesArr[scanIndex]
    }
  }

  syncRelateScoutCountAfterChangeScoutParams(series: BaseScanSeries) {
    series.nextRelatedSeries.forEach((seriesId: number | string) => {
      const relatedSeries = this.getSeriesById(seriesId)
      relatedSeries!.scoutCount = series.scoutCount
    })
  }




  appendScanSeries(series: BaseScanSeries | NormalScanSeries) {
    this.scanSeriesArr.push(series)
    this.updateActiveScanSeries(series)
  }

  updateScanSeries(newScanSeriesArr) {
    this.scanSeriesArr = newScanSeriesArr
  }

  relate2ScanSeries(prevSeriesId, nextSeriesId) {
    const prevSeries = this.getSeriesById(prevSeriesId)
    const nextSeries = this.getSeriesById(nextSeriesId)
    if (prevSeries === null || nextSeries === null) {
      return
    }
    prevSeries.nextRelatedSeries = [...prevSeries.nextRelatedSeries, nextSeries.id]
    nextSeries.prevRelatedSeries = [...nextSeries.prevRelatedSeries, prevSeries.id]
  }

  getFinishedSeries() {
    return this.scanSeriesArr.filter((series: BaseScanSeries | NormalScanSeries) => {
      return [ChooseScanType.helical, ChooseScanType.fault].includes(series.scanType) && series.status === EnumScanStatus.finish
    })
  }

  exeRemoveSeriesByIds(seriesIds: (number | string)[]) {
    seriesIds.forEach(seriesId => {
      const currentIndex = this.scanSeriesArr.findIndex(series => series.id === seriesId)
      this.scanSeriesArr.splice(currentIndex, 1)
    })
  }

  updateActiveAfterRemove() {
    let series = {
      id: '',
      scanType: ''
    }
    if (this.scanSeriesArr.length > 0) {
      series = {
        id: this.scanSeriesArr[this.scanSeriesArr.length - 1].id,
        scanType: this.scanSeriesArr[this.scanSeriesArr.length - 1].scanType
      }
    }
    this.updateActiveScanSeries(series)
  }

  async removeOneSeries(targetSeries: BaseScanSeries | NormalScanSeries) {
    try {
      await this.removeRelatedSeries(targetSeries)
      this.exeRemoveSeriesByIds([targetSeries.id])
      this.updateActiveAfterRemove()
    } catch (e) {

    }
  }

  removeRelatedSeries(targetSeries: BaseScanSeries | NormalScanSeries) {
    return new Promise((resolve, reject) => {
      if (targetSeries instanceof NormalScanSeries) {
        const relatedSeriesIds = targetSeries.prevRelatedSeries
        relatedSeriesIds.forEach(seriesId => {
          const series = this.getSeriesById(seriesId)
          if (series) {
            series.nextRelatedSeries = series.nextRelatedSeries.filter(relatedSeriesId => relatedSeriesId !== targetSeries.id)
          }
        })
        resolve('')
      } else {
        const relatedSeriesIds = targetSeries.nextRelatedSeries
        if (relatedSeriesIds.length > 0) {
          ElMessageBox.confirm(
            '删除平片将会删除关联的序列,确定?',
            'Warning',
            {
              confirmButtonText: 'OK',
              cancelButtonText: 'Cancel',
              type: 'warning'
            }
          )
            .then(() => {
              this.exeRemoveSeriesByIds(relatedSeriesIds)
              resolve('')
            })
            .catch(() => {
              reject('')
            })
        } else {
          resolve('')
        }
      }
    })
  }

  updateActiveScanSeries(scanSeries: BaseScanSeries | NormalScanSeries | { id: string, scanType: string }) {
    Object.assign(this.activeScanSeries, {
      id: scanSeries.id,
      scanType: scanSeries.scanType
    })
  }

  updateScanStatus(seriesArr, status: EnumScanStatus) {
    seriesArr.map(series => {
      series.status = status
    })
  }

  getWaitingScanSeries() {
    return this.scanSeriesArr.filter(seriesInfo => seriesInfo.status === EnumScanStatus.c_fit)
  }

  generateScoutId() {
    const waitingScanSeries = this.getWaitingScanSeries()
    waitingScanSeries.map((series: BaseScanSeries | NormalScanSeries) => {
      const seriesId = series.id

      if (!(series instanceof NormalScanSeries)) {
        const map = new Map()
        if (series.scoutCount === 1) {
          const imageId =  `${seriesId}_image_1`
          map.set(imageId, {})
          series.imageIds = [imageId]
          this.imageId2seriesIdMap.set(imageId, series.id)
        } else if (series.scoutCount === 2) {
          const imageId1 = `${seriesId}_image_1`
          const imageId2 = `${seriesId}_image_2`
          map.set(imageId1, {})
          map.set(imageId2, {})
          series.imageIds = [imageId1, imageId2]
          this.imageId2seriesIdMap.set(imageId1, series.id)
          this.imageId2seriesIdMap.set(imageId2, series.id)
        }
        series.eachScoutMap = map
      } else {
        const imageId =  `${seriesId}_image_1`
        this.imageId2seriesIdMap.set(imageId, series.id)
        series.imageIds = [imageId]
      }
    })
  }
}

const scanSeries = new ScanSeries()

export default scanSeries
